#include "event.h"
#include "entity.h"
#include "component.h"
#include "graphics.h"
#include "images_diffuse.h"
#include "button.h"
#include "shoehorn_sdl.h"
#include "player.h"
#include "enemy.h"
#include "tag.h"
#include "util.h"
#include "help_text.h"
#include "background.h"
#include "level.h"
#include "sounds.h"
#include "random.h"

#include <math.h>

entity *player;
//vec camera_goal;

declare_body(warp_crusher, { })
declare_tick(warp_crusher, { })

float warp_dist = 0;

declare_draw(warp_crusher, {
	draw_sprite(&sprite_warp_crush, -58 + warp_dist, 0);
	draw_sprite_flipped(&sprite_warp_crush, 198 - warp_dist, 0);
})

declare_head(warp_crusher)

static float test_y(entity *e) {
	float y = e->position.y;
	return y;
}

int predicate(entity *a, entity *b) {
	if(a->tag == TAG_TITLE) return 0;
	if(b->tag == TAG_TITLE) return 1;
	if(a->tag == TAG_WEAPON_CHOICE) return 0;
	if(b->tag == TAG_WEAPON_CHOICE) return 1;
	if(a->tag == TAG_CONTINUE) return 0;
	if(b->tag == TAG_CONTINUE) return 1;
	if(a->tag == TAG_HELP_TEXT) return 0;
	if(b->tag == TAG_HELP_TEXT) return 1;
	if(a->tag == TAG_WARP) return 0;
	if(b->tag == TAG_WARP) return 1;
	if(a->tag == TAG_EXPLOSION) return 0;
	if(b->tag == TAG_EXPLOSION) return 1;
	if(a->tag == TAG_BACKGROUND) return 1;
	if(b->tag == TAG_BACKGROUND) return 0;
	if(a->tag == TAG_BACKGROUND_PARTICLE) return 1;
	if(b->tag == TAG_BACKGROUND_PARTICLE) return 0;
	
	float ay = test_y(a);
	float by = test_y(b);
	
	return ay < by;
}

sound *s_player_shoot;
sound *s_enemy_explode;
sound *s_enemy_hit;
sound *s_player_hit;
sound *s_warp;

void init() {
	rand_init();
	
	sound_init();
	s_player_shoot = get_sound("snd/new_player_shoot.wav");
	s_enemy_explode = get_sound("snd/enemy_explode.wav");
	s_enemy_hit = get_sound("snd/enemy_hit.wav");
	s_player_hit = get_sound("snd/player_hurt.wav");
	s_warp = get_sound("snd/warp.wav");
	
	set_music("snd/music.wav");
	
	player = make_player();
	
	level_init();
	make_title();
	
	
	//camera_goal = v0();
	
	//make_satellite(vxy(100, 100), 1);
	//make_satellite(vxy(100, 200), 2);
	//make_satellite(vxy(100, 300), 3);
	//make_basic_spray(vxy(100, 130), 5);
	//make_basic_spray(vxy(50,  100), 5);
	//make_basic_spray(vxy(150, 100), 5);
	/*make_satellite_off(vxy( 25, 100), 3,  0);
	make_satellite_off(vxy( 50, 100), 3,  5);
	make_satellite_off(vxy( 75, 100), 3, 10);
	make_satellite_off(vxy(100, 100), 3, 15);
	make_satellite_off(vxy(125, 100), 3, 20);
	make_satellite_off(vxy(150, 100), 3, 25);
	make_satellite_off(vxy(175, 100), 3, 30);*/
	
	camera_position(vxy(0, 0));
	set_background(xrgb(0x190562));
	
	make_background();
	
	ent_set_predicate(predicate);
	
	entity *warp_crush_parent = ent_new();
	warp_crush_parent->tag = TAG_WARP;
	add_component(warp_crush_parent, c_new(warp_crusher));
}

//258ce9
//1043b3

float rspace = 0x19/255.f;
float gspace = 0x05/255.f;
float bspace = 0x62/255.f;
float rwarp = 0x10/255.f;
float gwarp = 0x43/255.f;
float bwarp = 0xb3/255.f;

float warp_dist_target = 0;

void warp_set(float target) {
	warp_dist_target = target;
}

//enemy_group enemy_groups[] = {
//	
//};

//#define GROUP_COUNT (sizeof(enemy_groups) / sizeof(enemy_groups[0]))
//size_t current_group = 0;


void loop() {
	ent_process();
	
	level_advance();
	
	warp_dist += (warp_dist_target - warp_dist) * 0.12f;
	if(fabs(warp_dist - warp_dist_target) < 0.2f) warp_dist = warp_dist_target;
	float t = warp_dist / 58.f;
	
	float warp_min = warp_dist;
	float warp_max = 198 - warp_dist;
	
	set_background(rgb(rspace + (rwarp - rspace) * t, gspace + (gwarp - gspace) * t, bspace + (bwarp - bspace) * t));
	t /= 10;
	colorify(1 + (rwarp - 1) * t, 1 + (gwarp - 1) * t, 1 + (bwarp - 1) * t);
	
	for_ent(e, ent_all(is_not(tagged(TAG_WARP)), is_not(tagged(TAG_BULLET)), is_not(tagged(TAG_HELP_TEXT)), is_not(tagged(TAG_CONTINUE))), {
		fclamp(&e->position.x, warp_min, warp_max);
	})
	
	//vec camera_target = vxy(0, player->position.y - 40);
	//camera_goal = vadd(camera_goal, vmul(vsub(camera_target, camera_goal), 0.8f));
	//vec c = vsub(camera_goal, vxy(0, 0));
	//camera_position(c);
	
	
}

float warp_fac() {
	return warp_dist / 58.f;
}